Fold views, also called folds, are views that always appear in pairs. They are only meaningful when embedded in texts. A pair, called the left and right fold, brackets a stretch of text and represent a second piece of text that is hidden. By clicking at a fold with the mouse, the stretch of text between the left and right fold is replaced with the hidden text, and the text that originally appeared between the folds becomes the hidden text. Clicking a second time at the same fold restores the original state. Because the primary use of folds is to hide longer stretches of text and replace them with a usually much shorter placeholder, a fold is said to be either in expanded or collapsed state. Try it!
text between collapsed folds
Folds can be nested, but the stretch between one pair of folds must not partially overlap another. Hierarchically nested folds are often used in program texts. By hiding a sequence of statements and writing a short comment between the collapsed folds, the resulting program text can be explored interactively in a top-down manner. Try it with this example!
PROCEDURE Enter (id: LONGINT; name: TextMappers.String; value: REAL);
enter a new value into the list
Instead of clicking manually through a deep hierarchy of folds, you can hold down the modifier key while clicking at the fold. This expands or collapses a fold and all nested folds.
The following menu entries operate on folds. Create Fold in menu Tools inserts a new pair of folds in the focus text. The current text selection in the focus text will be bracketed by the newly inserted folds. Expand All in menu Tools expands all folds in the focus text. Similarly, Collapse All collapses all folds in the focus text. Fold... in menu Tools opens a dialog box that lets you qualify which folds in the focus text to collapse or expand (see fig. 1, below). If the check box Nested is checked, all nested folds are collapsed or expanded. This corresponds to choosing Expand All or Collapse All fro the menu. If Nested is not checked, only the outermost folds in the nesting hierarchy are affected. For example, when you click Expand, only the outermost folds in the nesting hierarchy that are collapsed will be expanded. Checking Selective Fold enables the text entry field above the check box. By specifying a label value in this field, the set of folds affected can be restricted to those that have a label property matching the given string.
Fig. 1: The dialog box opened by menu item Fold...
Set Label... from menu Tools opens a dialog box to inspect and set the label property of a pair of folds (see fig. 2, below). The text field contains the label property value of the first fold in the current selection of the focus text. The entry field is diabled if no fold is contained in the text selection. The Set button sets the label property of the first fold contained in the text selection of the focus text. If no fold is contained in the selection when Set is pressed, the entry field will be disabled.
Fig. 2: The dialog box opened by menu item Set Label...
To describe the pre- and postconditions of procedures exported from StdFolds, we use the following pseudo-procedures.
Pos(f) designates the position of the fold view f in its hosting text.
0 <= Pos(f) < text.Length().
Stretch(p1, p2) stands for the text stretch [p1, p2) if p1 < p2 holds, or if p2 <= p1, then it denotes the text stretch [p2, p1).
Flipped(f) denotes the fold f in its dual, "flipped" state.
Returns the text stretch that is currently hidden by the pair (fold, Matching(fold)). The text should not be modified. If the hidden text stretch is of length zero, NIL is returned.
20 fold # NIL
Matching(fold) # NIL
[ let p1 := Pos(Flipped(fold)), p2 := Pos(Matching(Flipped(fold))) ]
ABS(p2 - p1) = 1 => result = NIL
ABS(p2 - p1) > 1 => result is Stretch(p1, p2)
Matching(fold) = NIL
result = NIL
PROCEDURE Flip (fold: Fold);
Changes the state of fold. The text stretch S between fold and Matching(fold) is replaced by the text HiddenText(fold). The stretch S will be the new hidden text.
If nested holds and label = "", all folds f in text with f.state = expanded are flipped. If ~nested, only the outermost folds in the nesting hierarchy are flipped. If label # "", only folds with f.label = label are flipped.
20 text # NIL
PROCEDURE ExpandFolds (text: TextModels.Model; nested: BOOLEAN; label: ARRAY OF CHAR);
If nested holds and label = "", all folds f in text with f.state = collapsed are flipped. If ~nested, only the outermost folds in the nesting hierarchy are flipped. If label # "", only folds with f.label = label are flipped.
20 text # NIL
PROCEDURE Collapse
Collapse all fold views in the focus text.
PROCEDURE Expand
Expand all fold views in the focus text.
PROCEDURE ZoomOut
Collapse all outermost expanded fold views in the focus text.
PROCEDURE ZoomIn
Expand all outermost collapsed views in the focus text.
the text stretch [beg, end) does not partially overlap a pair of folds
Pos(f1) = beg
Pos(f2) = end+1
Matching(f1) = f2
f1.state = f2.state = state
HiddenText(f1) = NIL
the text stretch [beg, end) partially overlaps a pair of folds
nothing is done
PROCEDURE CreateGuard (VAR par: Dialog.Par)
Sets par.disabled to TRUE when the text selection in the current focus text partially overlaps a pair (f, Matching(f)) of fold views. par.disabled is also set to TRUE if the focus text is shown in browser mode or mask mode, that is if the text cannot be modified.
PROCEDURE Create (state: LONGINT)
If CreateGuard holds, creates a a new pair of fold views and inserts them into the focus text, bracketing the current text selection or the caret position. Calls Insert(FocusText, selBeg, selEnd, state).